不知什么来源的题目
来源:https://kirin-say.top/2019/11/06/QEMU-Escape-in-Cloud-Security-Game/
漏洞:也不能说漏洞,在mmio_read里面直接给了system的后门
1 | signed __int64 __fastcall rfid_read(__int64 a1, unsigned __int64 a2) |
利用:通过rfid_write将code赋值为跟magic_code相等,再设置一下command,最后调用rfid_read即可完成逃逸
BlizzardCTF 2017 Strng
题目链接:https://github.com/rcvalle/blizzardctf2017
漏洞:在pmio中对于数组的索引没有限制,导致越界读写
1 | uint64_t __fastcall strng_pmio_read(STRNGState *opaque, hwaddr addr, unsigned int size) |
利用:
1、通过数组越界,获得任意读写来泄露函数指针,计算出system函数地址
2、之后改写rand_r函数指针为system,调用rand_r函数即可劫持控制流
HITB-GSEC-2017-babyqemu
题目下载:https://github.com/kitctf/writeups/blob/master/hitb-gsec-2017/babyqemu/babyqemu.tar.gz
漏洞:也是对于dma_buf数组的索引没有限制,导致任意地址读写,只不过这个题目需要我们将虚拟地址转化为物理地址
1 | void __fastcall hitb_dma_timer(HitbState *opaque) |
利用:
1、通过数组越界读泄露函数指针enc,由于这个qemu-system-x86_64的导入表有system,所以我们直接可以算出system
2、用system覆盖enc函数
3、写入opaque->dma_buf为要执行的命令,比如cat flag
4、使用cmd=1|2|4时,调用enc函数,劫持控制流
QEMU Escape — vm_escape from 0CTF 2017 Finals
没有公开下载的题目
wp: https://blog.eadom.net/writeups/qemu-escape-vm-escape-from-0ctf-2017-finals-writeup/
漏洞:
1、对于phys_mem_write的len没有限制,导致可以越界读,同样用到了物理地址(需要将虚拟地址转化为物理地址)
2、uaf漏洞,在vdd_mmio_write中可以设置dma_timer的过期时间,而在vdd_dma_timer中调用了opaque->dma_state->phys_mem_read/write
,而pci_vdd_uninit
函数会将dma_state释放;所以加入pci_vdd_uninit
函数,在vdd_dma_timer
之前调用,就是uaf了。
利用:
1、通过phys_mem_write的越界读泄露程序地址还有libc地址(其实这里libc地址用不到,因为导入表有system了,只要程序地址加上偏移就行)
2、将我们要执行的命令复制到opaque->dma_buf
3、在vdd_mmio_write中可以设置dma_timer的过期时间
4、往/sys/bus/pci/slots/4/power
写入0,从而触发pci_vdd_uninit去free dma_state
5、通过vdd_linear_write申请dma_state同样大小的内存,并用正确的值填充,具体代码如下,主要是将cmd设置为2,而phys_mem_read函数指针,设置为system,最后上面的dma_timer时间到了就会调用opaque->dma_state->phys_mem_read,从而让我们劫持控制流
1 | void put_fake_dma(void) |
Defcon 2018 - EC3
题目:https://github.com/o-o-overflow/chall-ec-3
漏洞:在mmio_write中,free的时候,没有将指针置空,导致了uaf漏洞,就跟常规的堆题一样,使用fastbin attack
1 | void __fastcall ooo_mmio_write_6E61F4(__int64 opaque, __int64 addr, __int64 value, unsigned int size) |
利用:
1、在gbuf_bss_1317940中构0x7f绕过fastbin检查,比如在gbuf_bss_1317940[8]中存放malloc的返回值
2、利用fastbin attack获得指向gbuf_bss_1317940的指针
3、利用上面的指针,将free或者malloc的got地址写入到gbuf_bss_1317940[10]中
4、通过edit gbuf_bss_1317940[10]即可修改got表
5、最后调用free或者malloc即可劫持控制流,这里有个cat flag的后门函数,劫持到那即可
题目难点在于没有符号表,需要逆向,还有就是qemu自身也会申请或者释放0x60大小的堆,所以需要循环申请和循环修改提升成功率
强网杯 qwb 2019 final execchrome
题目:https://github.com/ray-cp/vm-escape/tree/master/qemu-escape/qwb-final-2019-ExecChrome
只有qemu-system-x86_64,可能需要修复需要的lib,需要的库超级多
漏洞:
1、 nvme_mmio_read存在越界读漏洞,也是对索引没有限制
1 | uint64_t __cdecl nvme_mmio_read(NvmeCtrl *opaque, hwaddr addr, unsigned int size) |
2、 在nvme_mmio_write中的nvme_write_bar函数中故意添加了代码,也是导致NvmeCtrl->bar.cap之后的0-0x1000偏移任意地址写
1 | if ( sizea == 2 ) |
漏洞利用:
1、利用nvme_mmio_read进行程序地址以及堆地址的泄露,got表中存在system,所以程序地址加一个偏移就得到了system got的地址
2、通过NvmeCtrl->bar.cap之后的0-0x1000偏移任意地址写,在bar后面的地址伪造一个admin_sq->timer
,timer中的cb设置为system got的地址
3、也是NvmeCtrl->bar.cap之后的0-0x1000偏移任意地址写,修改admin_cq->timer指针,指向上面伪造的timer
最后竟然通过只有通过重启动触发timer的调用…
XNUCA 2018 SSD
题目:https://github.com/w0lfzhang/vmescape/tree/master/xnuca
漏洞:还是常规的fastbin的uaf放到qemu里面,free的时候没将指针置空
1 | xnucaState *__fastcall xnuca_timer(xnucaState *State) |
漏洞利用:
通过fastbin attack伪造fd指向free got后,修改free got为system plt的地址,最后调用free即可
跟defcon ec3比,只不过这个有符号,但是给这个加了点限制,才能进入漏洞代码:
1、首先调用xnuca_timer
,先得调用xnuca_set_timer
初始化计时器
2、而进入计时器的初始化,需要State->cmd_9D0 & 1 == 1
,那就需要通过xnuca_auth
5次后设置a1->cmd_9D0 |= 1u;
3、最后进入xnuca_timer
中的漏洞代码,需要cmd_9D0 & 4 == 1
,这个可以通过调用xnuca_send_request
设置,不过也得必须调用xnuca_send_request
来传递我们的参数
跟defcon ec3不一样的还有malloc的返回值不是0x7fxxxxxxx,所以指向直接fd劫持到got表,修改free了
强网杯2019线上赛qwct
题目:https://github.com/ray-cp/vm-escape/tree/master/qemu-escape/qwb-preliminary-2019-qwct
漏洞:
通过strlen()到\x00才截止可以越界读
1 | v18 = strlen((const char *)opaque->crypto.output_buf); |
aes_encrypt_function和aes_decrypto_function都有8字节溢出
1 | if ( v7 ) |
漏洞利用:
1、mmio_write不能直接填充output_buf,所以我们通过调用stream_encrypto_fucntion去填充疑惑后都是非0的,那么strlen计算就会超过0x800,那就可以越界读,读取到函数指针stream_encrypto_fucntion的地址,从而算出程序的基址,及system_plt地址
2、虽然aes_encrypt_function和aes_decrypto_function都有8字节溢出,但是我们需要控制output_buf的值,我们才能最终控制计算出来的值(即循环异或,第一次是异或0,第二次是异或上一次的结果),直接通过aes_encrypt_function利用有点困哪,我们难以控制加密后的值。但是我们先aes加密,再通过aes解密,那么我们就可以精准控制解密结果了。
题外话
关注下有没常见套路整数溢出漏洞什么的
附录
关于exp传到qemu中
远程环境
- telnet:
telnet XXX.XXX.XXX.XXX 6666 > pwn.b64 && base64 -d pwn.b64 > pwn
- 有无wget
- 实在不行难道 echo?
本地环境
1、scp
2、sftp
3、文件系统打包
1 | //解压 |
调用计算器,浏览器
1 | // char *para="google-chrome –no-sandbox file:///home/qwb/Desktop/success.mp4"; |
msfvenom -p linux/x64/exec cmd=”export DISPLAY=:0.0&&xcalc” -f dw